package demo3

import (
	"fmt"
	"regexp"
)

/*
	panic
		1. 当宕机发生时，程序会中断运行，并立即执行在该 goroutine（可以先理解成线程）中被延迟的函数（defer 机制）。
			随后，程序崩溃并输出日志信息。日志信息包括 panic value 和函数调用的堆栈跟踪信息。panic value 通常是某种错误信息。
		2. 崩溃都表明代码中存在漏洞，所以对于大部分漏洞，我们应该使用 Go 提供的错误机制，而不是 panic，尽量避免程序的崩溃。
*/

// 输入包含正则表达式的字符串，返回正则表达式对象。
func test381(str string) *regexp.Regexp {
	reg, error := regexp.Compile(str)

	if error != nil {
		panic(`regexp: Compile(` + str + `):` + error.Error())
	}

	return reg
}

// 在宕机时触发延迟执行语句
func test382() {
	defer fmt.Println("panic 之前11")
	defer fmt.Println("panic 之前22")
	panic("paci test 382")
}

// TestDemo38 panic 宕机
func TestDemo38() {
	// demo1: 手动触发宕机
	// 	Go 语言可以在程序中手动触发宕机，让程序崩溃，这样开发者可以及时地发现错误，同时减少可能的损失。
	// 	Go 语言程序在宕机时，会将堆栈和 goroutine 信息输出到控制台，所以宕机也可以方便地知晓发生错误的位置。
	//	如果在编译时加入的调试信息甚至连崩溃现场的变量值、运行状态都可以获取，那么如何触发宕机呢

	// panic() 的参数可以是任意类型，后文将提到的 recover 参数会接收从 panic() 中发出的内容。
	// panic("crash")

	// demo2 在运行依赖的必备资源缺失时主动触发宕机
	// 在运行依赖的必备资源缺失时主动触发宕机
	// 手动宕机进行报错的方式不是一种偷懒的方式，反而能迅速报错，终止程序继续运行，防止更大的错误产生。
	// 不过，如果任何错误都使用宕机处理，也不是一种良好的设计。因此应根据需要来决定是否使用宕机进行报错。

	// test381("htts://www.xxx.com")

	// 当 panic() 触发的宕机发生时，panic() 后面的代码将不会被运行，
	// 但是在 panic() 函数前面已经运行过的 defer 语句依然会在宕机发生时发生作用

	test382()
}
